package com.niiwoo.civet.mobile.controller.refund;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.base.enums.OrderTradeSourceEnum;
import com.niiwoo.civet.base.enums.RefundTypeEnum;
import com.niiwoo.civet.mobile.vo.request.refund.AppNormalRefundRequestVO;
import com.niiwoo.civet.mobile.vo.request.refund.RepayQueryRequestVO;
import com.niiwoo.civet.mobile.vo.request.refund.RepayRequestVO;
import com.niiwoo.civet.mobile.vo.response.fefund.AppNormalRefundResponseVO;
import com.niiwoo.civet.mobile.vo.response.fefund.RefundGuideContentResponseVO;
import com.niiwoo.civet.mobile.vo.response.fefund.RepayQueryResponseVO;
import com.niiwoo.civet.mobile.vo.response.fefund.RepayResponseVO;
import com.niiwoo.civet.trade.dto.request.RefundRequestDTO;
import com.niiwoo.civet.trade.dto.response.RefundResponseDTO;
import com.niiwoo.civet.trade.dto.response.myloan.RefundGuideContentResponseDTO;
import com.niiwoo.civet.trade.service.newRefund.RefundDispatchDubboService;
import com.niiwoo.civet.trade.service.newRefund.RefundDubboService;
import com.niiwoo.civet.trade.service.newRefund.RefundHelperDubboService;
import com.niiwoo.tripod.web.annotation.AuthIgnore;
import com.niiwoo.tripod.web.util.PrincipalContext;
import com.niiwoo.tripod.web.vo.Empty;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;


@RestController
@RequestMapping("/refund")
@Api(tags = "还款: (宾村,王均)", description = "/refund")
@Slf4j
public class RefundController {

	@Reference(version = "1.0.0")
	private RefundDubboService refundDubboService;

	@Reference(version = "1.0.0")
	private RefundDispatchDubboService refundDispatchDubboService;

	@Reference(version = "1.0.0")
	private RefundHelperDubboService refundHelperDubboService;


	@PostMapping("/repayQuery")
	@ApiOperation("用户还款-还款查询（王均）")
	public Result<RepayQueryResponseVO> repayQuery(@RequestBody @Valid RepayQueryRequestVO requestVO)
	{
		log.info("RefundController ->repayQuery:refundOrderId={},requestVO={}",requestVO.getRefundOrderId(),requestVO);
		final RepayQueryResponseVO responseVO = new RepayQueryResponseVO();
		RefundResponseDTO  responseDTO = refundDispatchDubboService.refundQuery(requestVO.getRefundOrderId());
		BeanUtils.copyProperties(responseDTO,responseVO);
		return Result.with(responseVO);
	}

	@PostMapping("/repay")
	@ApiOperation("用户还款-新的还款入口（王均）")
	public Result<RepayResponseVO> repay(@RequestBody @Valid RepayRequestVO requestVO)
	{
		log.info("RefundController ->repay:projectId={},requestVO={}",requestVO.getProjectId(),requestVO);
		String userId = PrincipalContext.getUserId();
		RefundRequestDTO refundRequestDTO = new RefundRequestDTO();
		refundRequestDTO.setProjectId(requestVO.getProjectId());
		refundRequestDTO.setBorrowUserId(userId);
		refundRequestDTO.setRefundType(RefundTypeEnum.enumOf(requestVO.getRefundType()));
		refundRequestDTO.setOrderTradeSource(OrderTradeSourceEnum.APP);

		final RepayResponseVO responseVO = new RepayResponseVO();
		Long refundOrderId = refundDispatchDubboService.refund(refundRequestDTO);
		responseVO.setRefundOrderId(refundOrderId);
		return Result.with(responseVO);
	}


	@PostMapping("/appRepayment")
	@ApiOperation("用户还款")
	public Result<AppNormalRefundResponseVO> appRepayment(@RequestBody @Valid AppNormalRefundRequestVO requestVO) {
		log.info("RefundController ->appRepayment:projectId={},requestVO={}",requestVO.getProjectId(),requestVO);
		String userId = PrincipalContext.getUserId();
		AppNormalRefundResponseVO responseVO = new AppNormalRefundResponseVO();
		responseVO.setAppRefundStatus(Byte.valueOf("0"));

		RefundRequestDTO refundRequestDTO = new RefundRequestDTO();
		refundRequestDTO.setProjectId(requestVO.getProjectId());
		refundRequestDTO.setBorrowUserId(userId);
		refundRequestDTO.setRefundType((requestVO.getType() == 1)
				? RefundTypeEnum.OVERDEPT
				: RefundTypeEnum.IMMEDIATELY);
		refundRequestDTO.setOrderTradeSource(OrderTradeSourceEnum.APP);

		Long refundOrderId = refundDispatchDubboService.refund(refundRequestDTO);
		RefundResponseDTO responseDTO = refundDispatchDubboService.refundQuery(refundOrderId);
		BeanUtils.copyProperties(responseDTO,responseVO);
		responseVO.setRepaymentAmount(responseDTO.getRepaidAmount());
		responseVO.setToRefundAmount(responseDTO.getNeedRepayAmount());
		responseVO.setAppRefundStatus(Byte.valueOf("1"));
		return Result.with(responseVO);
	}

	@PostMapping("/refundGuideContent")
	@ApiOperation("APP用户还款引导页")
	public Result<RefundGuideContentResponseVO> refundGuideContent() {
		String userId = PrincipalContext.getUserId();
		RefundGuideContentResponseVO responseVO = new RefundGuideContentResponseVO();
		RefundGuideContentResponseDTO responseDTO = refundDubboService.refundGuideContent(userId);
		responseVO.setTitle(responseDTO.getTitle());
		responseVO.setAddressUrl(responseDTO.getAddressUrl());
		responseVO.setImgUrl(responseDTO.getImgUrl());
		responseVO.setIsRepaymentActivity(responseDTO.getIsRepaymentActivity());
		responseVO.setIsUpdateLimit(responseDTO.getIsUpdateLimit());
		log.info("用户还款引导页###返回数据responseVO={}", JSON.toJSONString(responseDTO));
		return Result.with(responseVO);
	}

	@PostMapping("/autoWithhold")
	@ApiOperation("（内部接口）自动代扣")
	@AuthIgnore
	public Empty autoWithhold(String sign) {
        Assert.isTrue("niiwoo".equals(sign),"签名错误");
		RpcContext.getContext().asyncCall(() -> {refundHelperDubboService.withhold();});
		return Empty.getInstance();
	}

	@PostMapping("/withholdForOverdue50Day")
	@ApiOperation("（内部接口）代扣逾期50天")
	@AuthIgnore
	public Empty withholdForOverdue50Day(String sign) {
		Assert.isTrue("niiwoo".equals(sign),"签名错误");
		log.info("代扣逾期50天 start");
		refundHelperDubboService.withholdForOverdue50Day();
		return Empty.getInstance();
	}

	@PostMapping("/autoRepaymentNotEnough")
	@ApiOperation("（内部接口）00：15非全额自动划扣")
	@AuthIgnore
	public Empty autoRepaymentNotEnough(String sign) {
        Assert.isTrue("niiwoo".equals(sign),"签名错误");
		RpcContext.getContext().asyncCall(() -> {refundHelperDubboService.partialRefund();});
		return Empty.getInstance();
	}


	@PostMapping("/autoRepaymentEnough")
	@ApiOperation("（内部接口）全额自动划扣")
	@AuthIgnore
	public Empty autoRepaymentEnough(String sign) {
        Assert.isTrue("niiwoo".equals(sign),"签名错误");
		RpcContext.getContext().asyncCall(() -> {refundHelperDubboService.fullRefund();});
		return Empty.getInstance();
	}


	@PostMapping("/autoGuarantee")
	@ApiOperation("（内部接口）autoGuarantee,只执行垫付，")
	@AuthIgnore
	public Empty autoGuarantee(String sign) {
	    Assert.isTrue("niiwoo".equals(sign),"签名错误");
		RpcContext.getContext().asyncCall(() -> {refundHelperDubboService.compensatoryRefund();});
		return Empty.getInstance();
	}


	@PostMapping("/repeatDetailOrder")
	@ApiOperation("手动重发部分失败明细")
	@AuthIgnore
	public Empty repeatDetailOrder(Long refundOrderId) {
		Assert.notNull(refundOrderId,"refundOrderId不可空");
		refundDubboService.repeatDetailOrder(refundOrderId);
		return Empty.getInstance();
	}

	@PostMapping("/jobWithhold")
	@ApiOperation("（内部接口）手动job代扣")
	@AuthIgnore
	public Empty jobWithhold(String projectIds,String sign) {
		Assert.isTrue("niiwoo".equals(sign),"签名错误");
		Assert.notNull(projectIds,"projectIds");
		RpcContext.getContext().asyncCall(() -> {refundHelperDubboService.testWithhold(projectIds);});
		return Empty.getInstance();
	}
	@PostMapping("/jobCompensatoryRefund")
	@ApiOperation("（内部接口）手动job垫付")
	@AuthIgnore
	public Empty jobCompensatoryRefund(String projectIds,String sign) {
		Assert.isTrue("niiwoo".equals(sign),"签名错误");
		Assert.notNull(projectIds,"projectId不可空");
		RpcContext.getContext().asyncCall(() -> {refundHelperDubboService.testCompensatoryRefund(projectIds);});
		return Empty.getInstance();
	}
	@PostMapping("/calcPenaltyForProjectForWeb")
	@ApiOperation("（内部接口）手动更新指定标的罚息,projectId不为空时，只更新该标的罚息，不指定projectId则更新全部标的罚息")
	@AuthIgnore
	public Empty calcPenaltyForProjectForWeb(Long projectId,String sign) {
		Assert.isTrue("niiwoo".equals(sign),"签名错误");
		RpcContext.getContext().asyncCall(new Runnable() {
			@Override
			public void run() {
				refundHelperDubboService.calcPenaltyForProjectForWeb(projectId);
			}
		});
		return Empty.getInstance();
	}

	@PostMapping("/jobTestfund")
	@ApiOperation("（内部接口）手动job部分还款")
	@AuthIgnore
	public Empty jobTestRefund(String isFull,String projectIds,String sign) {
		Assert.isTrue("niiwoo".equals(sign),"签名错误");
		Assert.notNull(projectIds,"projectIds不可空");
		Assert.notNull(isFull,"isFull不可空");
		RpcContext.getContext().asyncCall(() -> {refundHelperDubboService.testRefund(isFull,projectIds);});
		return Empty.getInstance();
	}
}
